/*

 OPENGL TESTS
 
 */

//Import Statements
import processing.opengl.*;
import javax.media.opengl.*;
import com.sun.opengl.util.*;
import java.nio.FloatBuffer;
import msafluid.*;
import fullscreen.*;
import com.sun.opengl.util.j2d.*;

//Global Declerations
PaddleSystem paddleSystem;
BallSystem ballSystem;
/* MSA Stuff */
final float FLUID_WIDTH = 100;
float invWidth, invHeight;
float aspectRatio, aspectRatio2;
MSAFluidSolver2D fluidSolver;
ParticleSystem particleSystem;
BlockSystem blockSystem;
PImage imgFluid;
boolean drawFluid = true;
/* END MSA Stuff */
FullScreen fs;
TextRenderer renderer;

float[] x; float[] y;
float[] px; float[] py;
float[] vx; float[] vy;

void setup() {
  size(500,500,OPENGL);
  //fs = new FullScreen(this); 
  //fs.enter();
  renderer = new TextRenderer(new Font("Monospaced", Font.PLAIN,10));
  background(0);
  hint(ENABLE_OPENGL_4X_SMOOTH);

  paddleSystem = new PaddleSystem();
  ballSystem = new BallSystem();
  blockSystem = new BlockSystem(2);

  /* MSA STUFF */
  invWidth = 1.0f/width;
  invHeight = 1.0f/height;
  aspectRatio = width * invHeight;
  aspectRatio2 = aspectRatio * aspectRatio;

  // create fluid and set options
  fluidSolver = new MSAFluidSolver2D((int)(FLUID_WIDTH), (int)(FLUID_WIDTH * (height)/width));
  fluidSolver.enableRGB(true).setFadeSpeed(0.005).setDeltaT(0.5).setVisc(0.0003);

  // create image to hold fluid picture
  imgFluid = createImage(fluidSolver.getWidth(), (int)(fluidSolver.getHeight()), RGB);

  // create particle system
  particleSystem = new ParticleSystem();

  // init TUIO
  initTUIO();
  /* END MSA STUFF */
}

void draw() {
  updateTUIO();
  fluidSolver.update();
  if(drawFluid) {
    for(int i=0; i<(fluidSolver.getNumCells()); i++) {
      int d = 2;
      imgFluid.pixels[i] = color(fluidSolver.r[i] * d, fluidSolver.g[i] * d, fluidSolver.b[i] * d);
    }  
    imgFluid.updatePixels();  //fastblur(imgFluid, 2);
    image(imgFluid, 0, 0, width, height*.8);
  } 

  paddleSystem.updateAndDraw();

  x = new float[ballSystem.maxBalls];
  y = new float[ballSystem.maxBalls];
  px = new float[ballSystem.maxBalls];
  py = new float[ballSystem.maxBalls];
  vx = new float[ballSystem.maxBalls];
  vy = new float[ballSystem.maxBalls];

  for(int i = 0; i < ballSystem.curIndex; i++) {
    px[i] = ballSystem.balls[i].xpos;
    py[i] = ballSystem.balls[i].ypos;
  }
  ballSystem.updateAndDraw();
  for(int i = 0; i < ballSystem.curIndex; i++) {
    x[i] = ballSystem.balls[i].xpos * invWidth;
    y[i] = ballSystem.balls[i].ypos * invHeight*1.25;
    vx[i] = (ballSystem.balls[i].xpos - px[i]) * invWidth;
    vy[i] = (ballSystem.balls[i].ypos - py[i]) * invHeight;
    addForce(x[i]*random(.95,1.05), y[i]*random(.95,1.05), vx[i]*random(.95,1.05), vy[i]*random(.95,1.05));
    addForce(x[i]*random(.95,1.05), y[i]*random(.95,1.05), vx[i]*random(.95,1.05), vy[i]*random(.95,1.05));
    addForce(x[i]*random(.95,1.05), y[i]*random(.95,1.05), vx[i]*random(.95,1.05), vy[i]*random(.95,1.05));
    addForce(x[i]*random(.95,1.05), y[i]*random(.95,1.05), vx[i]*random(.95,1.05), vy[i]*random(.95,1.05));
  }
  particleSystem.updateAndDraw();
  blockSystem.updateAndDraw();
  renderer.beginRendering(width,height);
  renderer.setColor(1.0f, 1.0f, 1.0f, 1.0f);
  renderer.draw("jogl_tests: Jamal Mahboob", 10,10);
  try{
    renderer.draw("Ball XY: "+ballSystem.balls[0].xpos+","+ballSystem.balls[0].ypos,200,10);
    renderer.draw(""+ballSystem.curIndex,400,10);
  } catch(NullPointerException e) {};
  renderer.endRendering();
}

void mouseMoved() {
  paddleSystem.addPaddle();
}

void mouseClicked() {
  ballSystem.addBall();
}

void keyPressed() {
  ballSystem.removeBall();
}

void addForce(float x, float y, float dx, float dy) {
  float speed = dx * dx  + dy * dy * aspectRatio2;    // balance the x and y components of speed with the screen aspect ratio

  if(speed > 0) {
    if(x<0) x = 0; 
    else if(x>1) x = 1;
    if(y<0) y = 0; 
    else if(y>1) y = 1;

    float colorMult = 5;
    float velocityMult = 30.0f;

    int index = fluidSolver.getIndexForNormalizedPosition(x, y);

    color drawColor;

    colorMode(HSB, 360, 1, 1);
    float hue = ((x + y) * 180 + frameCount) % 360;
    drawColor = color(hue, 1, 1);
    colorMode(RGB, 1);  

    fluidSolver.rOld[index]  += red(drawColor) * colorMult;
    fluidSolver.gOld[index]  += green(drawColor) * colorMult;
    fluidSolver.bOld[index]  += blue(drawColor) * colorMult;

    particleSystem.addParticles(x * width, y * height*.8, 10);
    fluidSolver.uOld[index] += dx * velocityMult;
    fluidSolver.vOld[index] += dy * velocityMult;
  }
}





